home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvi2ps / oostrum / findfile.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  6KB  |  243 lines

  1. /* findfile.c
  2.  * Copyright 1985 Massachusetts Institute of Technology
  3.  * Modifications for BSD4.1 by Piet van Oostrum - RUU - 16 May 1986
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #ifdef PK
  9. #define EXT "pk"
  10. #define EXTL 2
  11. #define MAG 20
  12. #else
  13. #define EXT "pxl"
  14. #define EXTL 3
  15. #define MAG 4
  16. #endif
  17.  
  18. #ifdef BSD4.1
  19.  
  20. #include <dir.h>
  21. #define DIR FILE
  22. struct direct {
  23.     short d_namlen;
  24.     char d_name[DIRSIZ+1];
  25. };
  26. #define MAXNAMLEN 255
  27. #define opendir(dir) fopen(dir,"r")
  28. #define closedir(dir) fclose(dir)
  29. struct direct *readdir(dirp)
  30. DIR *dirp;
  31.  
  32. {
  33.     static struct dir dentry;
  34.     static struct direct de;
  35.     register int j;
  36.  
  37.     for (;;) {
  38.         if (fread((char *)&dentry, sizeof(dentry), 1, dirp) != 1)
  39.             return (NULL);
  40.         if (dentry.d_ino==0
  41.          || dentry.d_name[0]=='.' &&  (dentry.d_name[1]=='\0'
  42.             || dentry.d_name[1]=='.' && dentry.d_name[2]=='\0'))
  43.             continue;
  44.         for (j=0; j<DIRSIZ; j++)
  45.             de.d_name[j] = dentry.d_name[j];
  46.         de.d_name[DIRSIZ] = '\0';
  47.         de.d_namlen = strlen (de.d_name);
  48.         return (&de);
  49.     }
  50. }
  51.  
  52. #else BSD4.1
  53.  
  54. #include <sys/dir.h>
  55.  
  56. #endif BSD4.1
  57.  
  58. #include "findfile.h"
  59.  
  60. int
  61. findfileindir(area, name, mag, s, nname, nmag)
  62.      char *area,*name,*s,*nname;
  63.      int mag,*nmag;
  64. {
  65.   FILE *f;
  66.   char buf[BUFSIZ];
  67.   int found = 0;
  68.     
  69.   sprintf(s,"%s/SUBDIR",area);
  70.   if (!access(s,0)) sprintf(s,"%s/%s/%s.%d",area,name,name,mag);
  71.   else sprintf(s,"%s/%s.%d",area,name,mag);
  72.   strcat(s,EXT);
  73.   if (!access(s,4)) {
  74.     strcpy(nname,name);
  75.     *nmag = mag;
  76.     return(-1);
  77.   } else {
  78.     sprintf(buf,"%s/NEEDED",area);
  79.     if (!access(buf,2)) {
  80.       sprintf(s,"%s.%d",name,mag);strcat(s,EXT);strcat(s,"\n");
  81.       f = fopen(buf,"r+");
  82.       while (fgets(buf,sizeof(buf),f)) if (!strcmp(buf,s)) found++;
  83.       if (!found) fputs(s,f);
  84.       fclose(f);
  85.     }
  86.     return(0);
  87.   }
  88. }
  89.  
  90.  
  91. /* true if it found a file, false otherwise; name is in s */
  92. int findfile(dirvec,dirveclen,area, name, mag, s, nname, nmag)
  93.      char *dirvec[],*area,*name,*s,*nname;
  94.      int dirveclen,mag,*nmag;
  95. {
  96.   int i,point;
  97.   char family[128];
  98.  
  99.   strcpy(nname,name);
  100.   *nmag = mag;
  101.   point = -1;
  102.   (void) sscanf(name,"%[^0123456789.]%d",family,&point);
  103.  
  104.   /* First check dir area given in DVI file */
  105.   if (*area && findfileindir(area, name, mag, s, nname, nmag)) return(-1);
  106.   
  107.   /* Then check along dirvec */
  108.   for (i = 0; i < dirveclen; i++) 
  109.     if (findfileindir(dirvec[i], name, mag, s, nname, nmag)) return(-1);
  110.  
  111.   /* next check for closest magnification along dirvec */
  112.   return(findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag));
  113. }
  114.   
  115. int strdiff(s1,s2)
  116.      char *s1,*s2;
  117. {
  118.   register int diff = 0;
  119.  
  120.   while (*s1 && *s2) diff += abs(*s1++ - *s2++);
  121.   while (*s1) diff += *s1++;
  122.   while (*s2) diff += *s2++;
  123.   return(diff);
  124. }
  125.  
  126. scanpdir(dir,name,
  127.      family,point,mag,
  128.      bestfamily,bestname,bestpoint,bestmag,
  129.      min_df,min_dp,min_dm)
  130.      char *dir,*name,*family,*bestfamily,*bestname;
  131.      int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
  132. {
  133.   DIR *dirstream;
  134.   struct direct *dirrecord;
  135.   char qfamily[128];
  136.   int qpoint,qmag,df,dp,dm;
  137. #ifdef BSD4.1
  138.   char ext[20];
  139. #endif
  140.  
  141.   if (dirstream = opendir(dir)) {
  142.     while (dirrecord = readdir(dirstream)) {
  143. #ifndef BSD4.1
  144.       if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-EXTL,EXT))
  145. #endif BSD4.1
  146.       {
  147.     qpoint = -1; qmag = -1;
  148. #ifdef BSD4.1
  149.     (void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d%s",
  150.               qfamily,&qpoint,&qmag,ext);
  151.     if (strcmp(ext, EXT, strlen(ext))) continue;
  152. #else
  153.     (void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d",
  154.               qfamily,&qpoint,&qmag);
  155. #endif
  156.     df = strdiff(family,qfamily);
  157.     dp = abs(point - qpoint);
  158.     dm = abs(mag - qmag);
  159.     if ((df < *min_df)
  160.         || (df == *min_df && dp < *min_dp)
  161.           || (df == *min_df && dp == *min_dp && dm < *min_dm)) {
  162.         sprintf(bestname,"%s/%s",dir,dirrecord->d_name);
  163.         strcpy(bestfamily,qfamily);
  164.         *bestpoint = qpoint;
  165.         *bestmag = qmag;
  166.         *min_df = df;
  167.         *min_dp = dp;
  168.         *min_dm = dm;
  169.       }
  170.       }
  171.     }
  172.     closedir(dirstream);
  173.   }
  174. }
  175.  
  176. scandir(dir,name,
  177.     family,point,mag,
  178.     bestfamily,bestname,bestpoint,bestmag,
  179.     min_df,min_dp,min_dm)
  180.      char *dir,*name,*family,*bestfamily,*bestname;
  181.      int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
  182. {
  183.   DIR *dirstream;
  184.   struct direct *dirrecord;
  185.   int df;
  186.   char pdir[MAXNAMLEN];
  187.  
  188.   if (dirstream = opendir(dir)) {
  189.     while (dirrecord = readdir(dirstream)) {
  190.       if (dirrecord->d_name[0] != '.') {
  191.     df = strdiff(name,dirrecord->d_name);
  192.     if (df <= *min_df) {
  193.       sprintf(pdir,"%s/%s",dir,dirrecord->d_name);
  194.       scanpdir(pdir,name,
  195.            family,point,mag,
  196.            bestfamily,bestname,bestpoint,bestmag,
  197.            min_df,min_dp,min_dm);
  198.     }
  199.       }
  200.     }
  201.     closedir(dirstream);
  202.   }
  203. }
  204.  
  205.  
  206. /* finds the best match to the desired font */
  207. int findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag)
  208.      char *dirvec[],*family,*name,*s,*nname;
  209.      int dirveclen,point,mag,*nmag;
  210. {
  211.   char foo[MAXNAMLEN],bestname[MAXNAMLEN],bestfamily[128];
  212.   int min_df,min_dp,min_dm,df,dp,dm,i,bestpoint,bestmag;
  213.   
  214.   bestname[0] = '\0'; 
  215.   min_df = min_dp = min_dm = 9999999;
  216.   for (i = 0; i < dirveclen; i++) {
  217.     sprintf(foo,"%s/SUBDIR",dirvec[i]);
  218.     if (!access(foo,0)) scandir(dirvec[i],name,
  219.                 family,point,mag,
  220.                 bestfamily,bestname,&bestpoint,&bestmag,
  221.                 &min_df,&min_dp,&min_dm);
  222.     else scanpdir(dirvec[i],name,
  223.           family,point,mag,
  224.           bestfamily,bestname,&bestpoint,&bestmag,
  225.           &min_df,&min_dp,&min_dm);
  226.   }
  227.   if (bestname[0]) {
  228.     if (bestpoint > 0) sprintf(nname,"%s%d",bestfamily,bestpoint);
  229.     else strcpy(nname,bestfamily);
  230.     *nmag = bestmag;
  231.     strcpy(s,bestname);
  232.     if ((strcmp(bestfamily,family)
  233.      || bestpoint != point || abs(bestmag - mag) > 2)) 
  234.       fprintf(stderr,
  235.           "Substituted font %s at mag %d for %s at mag %d.\n",
  236.           nname,(bestmag * MAG + 3) / 6,
  237.           name,(mag * MAG + 3) / 6);
  238.     return(-1);
  239.   }
  240.   return(0);
  241. }
  242.   
  243.